/*
 * @Author: 肖思汗 
 * @Date: 2025-06-16 15:18:12 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2025-09-03 13:35:50
 */

// @ts-nocheck
import Taro from "@tarojs/taro";
import { autorun } from "mobx";
import utils from "src/utils/utils";
import { GLTFLoader } from '../../myThree/examples/jsm/loaders/GLTFLoader';
import { WechatPlatform } from '../../myThree/src/WechatPlatform';

import {
    AmbientLight, BackSide, Box3, Color, FrontSide, Group,
    AxesHelper,
    LinearEncoding,
    WebGLRenderTarget,
    ShaderMaterial,
    ShaderChunk,
    NoBlending,
    MeshBasicMaterial, MeshStandardMaterial, Object3D, OrthographicCamera, PerspectiveCamera,
    PLATFORM, PointLight, Scene, Vector3, WebGL1Renderer
} from '../../myThree/build/three.module';

import { OrbitControls } from './OrbitControls';
import designerStore from "../../Designer/designerStore";
import textureManager from "../../textureManager";
import { GoodsBaseData } from "types/type";
import preView2D3DStore from "./preView2D3DStore";
import fsQuad from "./pass/fsQuad";
import fileCache from "src/utils/fileCache";
import { clamp, isEmpty } from "lodash";

// 2d 3d 模型都在这个对象里面
class Perview3der {

    constructor() {
    }

    platform; //WechatPlatform
    renderer; //
    scene = new Scene();
    controls;//OrbitControls

    // 是否准备好了
    isReady = false;

    camera = (() => {
        const camera = new PerspectiveCamera(75, 1 / 1, 0.001, 100);
        camera.position.set(0, 0, 10);
        camera.lookAt(new Vector3(0, 0, 0));
        return camera;
    })();

    //正交相机
    orthographicCamera = (() => {
        const orthographicCamera = new OrthographicCamera(-5, 5, 5, -5);
        orthographicCamera.position.set(0, 0, 10);
        orthographicCamera.lookAt(new Vector3(0, 0, 0));
        return orthographicCamera;
    })();

    // 环境光
    ambientLight = (() => {
        const ambientLight = new AmbientLight('#fff', 0.7);
        this.scene.add(ambientLight);
        return ambientLight;
    })();

    // 点光源1
    pointLight1 = (() => {
        const pointLight = new PointLight('#fff', 0.4);
        pointLight.position.set(2, 0, 20);
        pointLight.decay = 0.2;
        pointLight.distance = 30;
        this.scene.add(pointLight);
        return pointLight;
    })();

    // 点光源2
    pointLight2 = (() => {
        const pointLight = new PointLight('#fff', 0.4);
        pointLight.position.set(-2, 0, -20);
        pointLight.decay = 0.2;
        pointLight.distance = 30;
        this.scene.add(pointLight);
        return pointLight;
    })();

    loader = new GLTFLoader();

    canvas;

    // 基础纹理渲染目标
    baseRenderTarget = new WebGLRenderTarget(1024, 1024);
    // 基础纹理渲染着色器
    baseMaterial = new ShaderMaterial({
        uniforms: {
            map: { value: this.baseRenderTarget.texture }, // 贴图纹理
        },
        vertexShader: `
        ${ShaderChunk.common}
        ${ShaderChunk.logdepthbuf_pars_vertex}
        varying vec2 vUv;
        void main() {
            vUv = uv;
            // gl_Position = vec4(position, 1.0);
            // gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
            ${ShaderChunk.logdepthbuf_vertex}
        }
    `,
        fragmentShader: `
        ${ShaderChunk.logdepthbuf_pars_fragment}
        uniform sampler2D map;
        varying vec2 vUv;
        void main() {
            gl_FragColor = sRGBToLinear(texture2D(map, vUv));
            ${ShaderChunk.logdepthbuf_fragment}
        }
    `,
        blending: NoBlending, // 渲染时不与背景融合计算 直接替换
        depthTest: true,
        depthWrite: true,
        transparent: true
    });

    // 坐标轴
    // axesHelper = (() => {
    //     const axesHelper = new AxesHelper(100);
    //     this.scene.add(axesHelper);
    //     return axesHelper;
    // })();

    // 初始化
    init(canvas) {
        if (this.canvas === canvas) {
            this.requestRender();
            return;
        }
        this.canvas = canvas;
        const platform = new WechatPlatform(canvas); // webgl canvas
        platform.enableDeviceOrientation('normal'); // 开启DeviceOrientation
        PLATFORM.set(platform);
        this.platform = platform;

        this.renderer = new WebGL1Renderer({
            alpha: true,
            antialias: true,
            // precision: 'highp',
            // powerPreference: 'high-performance',
            preserveDrawingBuffer: true

            // alpha: true
            // antialias: false
            // depth: true
            // premultipliedAlpha: true
            // preserveDrawingBuffer: true
            // stencil: true
        });

        // this.renderer.setPixelRatio(utils.pixelRatio);
        this.renderer.outputEncoding = LinearEncoding;

        //准备好了
        this.isReady = true;
        this.renderer.setSize(1024, 1024);

        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        this.controls.enableZoom = false;
        this.controls.enableDamping = true;
        this.controls.dampingFactor = 0.1;
        this.controls.enablePan = false;
        this.controls.addEventListener("change", async () => {
            await new Promise(resolve => setTimeout(resolve, 0));
            this.requestRender();
        });
        this.requestRender();
    }

    // 设置灯光强度
    setIntensity(intensity) {
        this.pointLight1.intensity = intensity;
        this.pointLight2.intensity = intensity;
        this.requestRender();
    }
    //销毁
    dispose() {
        this.front_cloth.traverse(child => {
            if (child.material) child.material.dispose();
            if (child.geometry) child.geometry.dispose();
        });
        this.front_cloth.clear();
        this.back_cloth.traverse(child => {
            if (child.material) child.material.dispose();
            if (child.geometry) child.geometry.dispose();
        });
        this.back_cloth.clear();
    }

    touchDitance = 0

    touchStart = (e) => {
        const touchCount = e.touches.length;
        if (touchCount === 1) {
            this.platform.dispatchTouchEvent(e);
        } else if (touchCount > 1) {
            this.touchDitance = Math.sqrt(Math.pow(e.touches[0].x - e.touches[1].x, 2) + Math.pow(e.touches[0].y - e.touches[1].y, 2))
        }
    }

    touchMove = (e) => {
        const touchCount = e.touches.length;
        if (touchCount === 1) {
            this.platform.dispatchTouchEvent(e);
        } else if (touchCount > 1) {
            const newTouchDitance = Math.sqrt(Math.pow(e.touches[0].x - e.touches[1].x, 2) + Math.pow(e.touches[0].y - e.touches[1].y, 2));
            const scale = this.touchDitance / newTouchDitance;
            let { cameraDistance } = preView2D3DStore;
            preView2D3DStore.setCameraDistance(clamp(12, 2, scale * cameraDistance));
            this.touchDitance = newTouchDitance;
        }
        this.requestRender();
    }

    touchEnd = (e) => {
        this.platform.dispatchTouchEvent(e);
    }

    // 加载衣服模型对象(正面)
    front_cloth = (() => {
        const front_cloth = new Group();
        this.scene.add(front_cloth);
        return front_cloth;
    })();

    //衣服背面模型
    back_cloth = (() => {
        const back_cloth = new Group();
        this.scene.add(back_cloth);
        return back_cloth;
    })();

    // 加载衣服模型 必须是这个域名的 glb 未压缩文件
    // async loadCloth(url = "https://upload-custom.oss-cn-beijing.aliyuncs.com/gkRdLrXMu5gPNo6DuWU5JM.glb") {
    async loadCloth(url = "https://upload-custom.oss-cn-beijing.aliyuncs.com/model/111222.glb") {
        this.dispose();

        while (!this.isReady) {
            await new Promise(resolve => setTimeout(resolve, 100));
        }
        return new Promise(async (resolve, reject) => {
            // 补全地址
            let modelUrl = utils.ossSuffix(url);

            this.loader.load(modelUrl, (gltf) => {

                this.center(gltf.scene);
                this.scaleTo(gltf.scene, 10, ['x', 'y']);

                const meshs = [];
                gltf.scene.traverse(obj => {
                    if (obj.isMesh) {
                        meshs.push(obj);
                        this.uploadMeshMatrix(obj);

                        if (obj.material.normalMap) {
                            // obj.material.normalMap.wrapS = RepeatWrapping;
                            // obj.material.normalMap.wrapT = RepeatWrapping;
                            delete obj.material.normalMap;
                        }
                    }
                });

                meshs.map(mesh => {
                    // 正面模型
                    const frontMesh = mesh.clone();
                    frontMesh.material = mesh.material.clone();
                    frontMesh.material.setValues({
                        side: FrontSide,
                        roughness: 1,
                        metalness: 0,
                    });
                    this.front_cloth.add(frontMesh);

                    //反面模型
                    const BackMesh = mesh.clone();
                    BackMesh.material = mesh.material.clone();
                    BackMesh.material.setValues({
                        side: BackSide,
                        roughness: 1,
                        metalness: 0
                    });
                    this.back_cloth.add(BackMesh);
                });

                this.camera.position.set(0, 0, 10);
                this.camera.lookAt(new Vector3(0, 0, 0));
                this.render();
                resolve();
            }, undefined, (e) => {
                console.error('11111', e);
            });
        });
    }

    //更新每个部位的贴图 这个方法是需要在衣服模型和纹理都准备好了之后才执行的
    async updataClothMap(secondaryCraftName: GoodsBaseData["secondaryCraftName"]) {
        while (!this.isReady) {
            await new Promise(resolve => setTimeout(resolve, 30));
        }
        this.front_cloth.traverse(mesh => {
            if (mesh.isMesh) {
                const texture = textureManager.getTexture(mesh.name);
                if (texture) {
                    mesh.material.map = texture;
                }
                mesh.material.needsUpdate = true;
            }
        });

        this.mockupGroup.traverse(mesh => {
            if (mesh.isMesh) {

                if (mesh.material.map) {
                    mesh.material.map.encoding = LinearEncoding;
                }

                if (["升华"].includes(secondaryCraftName) && mesh.material.map) {
                    mesh.material = new MeshBasicMaterial({
                        transparent: mesh.material.transparent,
                        opacity: mesh.material.opacity,
                        alphaTest: mesh.material.alphaTest,
                        color: mesh.material.color,
                        side: mesh.material.side,
                        map: mesh.material.map,
                    });
                } else {
                    const transparentTexture = textureManager.getTransparentTexture(mesh.name.replace(/\d+$/, ''));
                    const texture = textureManager.getTexture(mesh.name.replace(/\d+$/, ''));

                    mesh.material = new MeshStandardMaterial({
                        // normalMap: mesh.material.normalMap,
                        transparent: true,
                        opacity: mesh.material.opacity,
                        alphaTest: 0.1,
                        color: mesh.material.color,
                        metalness: 0,
                        roughness: 0.8,
                        side: mesh.material.side,
                        map: (["升华"].includes(secondaryCraftName) ? texture : transparentTexture) || mesh.material.map,
                    });

                }

            }
        });

        this.colorMockupGroup.traverse(mesh => {
            if (mesh.isMesh) {

                if (mesh.material.map) {
                    mesh.material.map.encoding = LinearEncoding;
                }

                if (["升华"].includes(secondaryCraftName) && mesh.material.map) {
                    mesh.material = new MeshBasicMaterial({
                        transparent: mesh.material.transparent,
                        opacity: mesh.material.opacity,
                        alphaTest: mesh.material.alphaTest,
                        color: mesh.material.color,
                        side: mesh.material.side,
                        map: mesh.material.map,
                    });
                } else {
                    const transparentTexture = textureManager.getTransparentTexture(mesh.name.replace(/\d+$/, ''));
                    const texture = textureManager.getTexture(mesh.name.replace(/\d+$/, ''));
                    mesh.material = new MeshStandardMaterial({
                        // normalMap: mesh.material.normalMap,
                        transparent: true,
                        opacity: mesh.material.opacity,
                        alphaTest: 0.1,
                        color: mesh.material.color,
                        metalness: 0,
                        roughness: 0.8,
                        side: mesh.material.side,
                        map: (["升华"].includes(secondaryCraftName) ? texture : transparentTexture) || mesh.material.map,
                    });

                }

            }
        });

        // this.requestRender();
    }

    //初始化上身效果图 mockups:Array<string>
    async initMockups(mockups: Array<string> = [], initColor = "#ffffff") {
        // 颜色整体提亮避免黑色时看不到细节
        const colorObject = new Color(initColor);
        const max = Math.max(...colorObject.toArray());
        const colorInterval = 1 - max;
        colorObject.r += colorInterval * 0.01;
        colorObject.g += colorInterval * 0.01;
        colorObject.b += colorInterval * 0.01;

        while (!this.isReady) {
            await new Promise(resolve => setTimeout(resolve, 100));
        }

        this.mockupGroup.traverse(child => {
            if (child.material) child.material.dispose();
            if (child.geometry) child.geometry.dispose();
        });
        this.mockupGroup.clear();
        const promises: Array<Promise<Object3D>> = [];

        for (let i in mockups) {
            const mockup = mockups[i];
            promises.push(new Promise(async (resolve, reject) => {
                let modelUrl = utils.ossSuffix(mockup);
                this.loader.load(modelUrl, (gltf) => {
                    this.center(gltf.scene);
                    this.scaleTo(gltf.scene, 10, ['x', 'y']);
                    gltf.scene.visible = false;
                    // 设置衣服的初始颜色
                    gltf.scene.traverse((mesh) => {
                        if (/^cloth(\d+)?$/.test(mesh.name)) {
                            ((mesh).material).color.copy(colorObject);
                        }
                    });
                    resolve(gltf.scene);
                });
            }));
        }
        const object3Ds = await Promise.all(promises);
        if (object3Ds.length) {
            this.mockupGroup.add(...object3Ds);
        }
        preView2D3DStore.setMockupCount(mockups.length);
        this.requestRender();
    }

    mockupGroup = (() => {
        const mockupGroup = new Group();
        this.scene.add(mockupGroup);
        return mockupGroup;
    })();


    //初始化颜色对应上身效果图
    async initColorMockups(colorMockups: Array<string> = []) {

        while (!this.isReady) {
            await new Promise(resolve => setTimeout(resolve, 100));
        }

        this.colorMockupGroup.traverse(child => {
            if (child.material) child.material.dispose();
            if (child.geometry) child.geometry.dispose();
        });
        this.colorMockupGroup.clear();
        const promises: Array<Promise<Object3D>> = [];

        for (let i in colorMockups) {
            const mockup = colorMockups[i];
            promises.push(new Promise(async (resolve, reject) => {
                let modelUrl = utils.ossSuffix(mockup);
                this.loader.load(modelUrl, (gltf) => {
                    this.center(gltf.scene);
                    this.scaleTo(gltf.scene, 10, ['x', 'y']);
                    gltf.scene.visible = false;
                    resolve(gltf.scene);
                });
            }));
        }
        const object3Ds = await Promise.all(promises);
        if (!isEmpty(object3Ds)) {
            this.colorMockupGroup.add(...object3Ds);
        }
        preView2D3DStore.setColorMockupCount(colorMockups.length);
        this.requestRender();
    }

    // 颜色对应的上身效果图模型组
    colorMockupGroup = (() => {
        const colorMockupGroup = new Group();
        this.scene.add(colorMockupGroup);
        return colorMockupGroup;
    })();

    _box3 = new Box3();
    _size = new Vector3();
    _center = new Vector3();

    // 设置衣服的颜色
    setClothColor(color, fillType) {
        console.log('setClothColor');

        this.back_cloth.traverse((m) => {
            if (m.isMesh) {
                m.material.color.set(fillType === 0 ? "#ffffff" : color);
            }
        });

        // 优化衣服颜色不要太亮或者太黑
        const clothColor = new Color(color);
        const max = Math.max(...clothColor.toArray());
        const colorInterval = 1 - max;
        clothColor.r += colorInterval * 0.01;
        clothColor.g += colorInterval * 0.01;
        clothColor.b += colorInterval * 0.01;

        this.mockupGroup.traverse((mesh) => {
            if (mesh.isMesh) {
                if (/^cloth(\d+)?$/.test(mesh.name)) {
                    console.log('cloth', 1, clothColor);
                    mesh.material.color.copy(clothColor);
                }
            }
        });

        this.colorMockupGroup.traverse((mesh) => {
            if (mesh.isMesh) {
                if (/^cloth(\d+)?$/.test(mesh.name)) {
                    console.log('cloth', 1, clothColor);
                    mesh.material.color.copy(clothColor);
                }
            }
        });
    }

    // 获取模型大小
    getSize(object3d) {
        this._box3.setFromObject(object3d);
        this._box3.getSize(this._size);
        return this._size.clone();
    }
    //居中对象
    center(object3d) {
        this._box3.setFromObject(object3d);
        this._box3.getCenter(this._center);
        (object3d).position.subVectors((object3d).position, this._center);
        (object3d).updateMatrixWorld(true);
    }

    // 使用指定的维度(xyz)计算, 缩放至指定大小;
    scaleTo(
        object3d,
        size = 1,
        key = ["x", "y", "z"]
    ) {
        const originSize = this.getSize(object3d);
        const scale = size / Math.max(...key.map((k) => originSize[k]));
        if ((object3d).isObject3D) {
            (object3d).scale.multiplyScalar(scale);
            (object3d).updateMatrixWorld(true);
        } else if ((object3d).isBufferGeometry) {
            (object3d).scale(scale, scale, scale);
        }
    }

    //更新mesh矩阵
    uploadMeshMatrix(mesh) {
        if (mesh) {
            mesh.updateMatrixWorld(true);
            //吧mesh的世界矩阵分解到mesh的trs上
            mesh.matrixWorld.decompose(mesh.position, mesh.quaternion, mesh.scale);
        }
    }

    type: "2D" | "3D" = "3D"; // 2D

    // 上一次渲染的时间
    preRenderTime = -30;
    rendering = false; //是否在渲染中
    /**
     * 渲染画布
     */
    render() {
        if (this.renderer) {

            // this.renderer.setRenderTarget(this.baseRenderTarget);

            // 渲染2d或者3D 到渲染目标上去
            switch (this.type) {
                case "2D":
                    this.renderer.render(this.scene, this.orthographicCamera);
                    break;

                case "3D":
                    this.renderer.render(this.scene, this.camera);
                    this.controls.update();
                    break;
            }

            // this.renderer.setRenderTarget(null);
            // fsQuad.render(this.renderer, this.baseMaterial);

        }
    }

    // 节流渲染
    async requestRender() {
        if (this.rendering) {
            return;
        }
        this.rendering = true;
        const currentTime = Date.now();
        await new Promise(resolve => setTimeout(resolve, Math.max(50 - (currentTime - this.preRenderTime), 0)));
        this.preRenderTime = Date.now();
        this.render();
        this.preRenderTime = Date.now();
        this.rendering = false;
    }

    //离屏渲染对象
    offscreenCanvas = Taro.createOffscreenCanvas({
        type: '2d',
        width: 1024,
        height: 1024,
    });
    offscreenCtx = this.offscreenCanvas.getContext('2d');

    // 下载当前画布上看到的的内容
    async download() {
        if (this.canvas) {
            const filePath = await this.exportImage();

            // 没有同意或拒绝授权时,会发起一个询问
            await Taro.authorize({
                scope: 'scope.writePhotosAlbum'
            }).catch(err => { return err; });

            // 再次检查检查权限
            let { authSetting } = await Taro.getSetting();
            console.log('检查权限', 1, authSetting);

            if (!authSetting['scope.writePhotosAlbum']) {
                console.log('没有权限', 2, '发起提示');
                Taro.showModal({
                    title: '提示',
                    content: '需要您授权保存到相册',
                    success: (res) => {
                        if (res.confirm) {
                            // 打开设置页面让用户手动开启权限
                            Taro.openSetting({
                                success: (settingRes) => { }
                            });
                        }
                    }
                });
            } else {
                //保存到手机相册

                try {
                    await Taro.saveImageToPhotosAlbum({
                        filePath: filePath
                    });
                    console.log('下载成功', filePath);
                    Taro.showToast({
                        title: '下载成功'
                    });
                } catch (error) {
                    console.log('下载失败', filePath, error);
                    Taro.showToast({
                        title: '下载失败'
                    });
                }

            }

        }
    }

    // 获取前片的缩率图的本地图片路径
    exportImage(): Promise<string> {

        return new Promise(async (resolve, reject) => {
            switch (this.type) {
                case "2D":
                    this.renderer.render(this.scene, this.orthographicCamera);
                    break;
                case "3D":
                    this.renderer.render(this.scene, this.camera);
                    break;
                default:
                    break;
            }

            await new Promise(resolve => setTimeout(resolve, 500));

            // 苹果手机的处理方式
            // if (utils.isIPhone) {
            //     // 将 WebGL 内容绘制到离屏 Canvas
            //     this.offscreenCtx.clearRect(0, 0, 1024, 1024);
            //     this.offscreenCtx.drawImage(this.canvas, 0, 0, 1024, 1024);
            //     // 导出 2D Canvas
            //     Taro.canvasToTempFilePath({
            //         canvas: this.offscreenCanvas,
            //         success: async (res) => {
            //             resolve(res.tempFilePath);
            //         }
            //     });

            // } else {
            const base64 = await this.canvas.toDataURL('image/png', 1);
            console.log("base64Lenth", base64.length);
            console.log(base64.substring(0, 200), "...");
            // 将base64转换为临时文件路径并保存到相册
            const filePath = `${Taro.env.USER_DATA_PATH}/${new Date().valueOf()}.png`;
            Taro.getFileSystemManager().writeFile({
                filePath: filePath,
                data: base64.replace(/^data:image\/\w+;base64,/, ''),
                encoding: 'base64',
                success: () => {
                    console.log(filePath);
                    resolve(filePath);
                    console.log('文件保存成功', filePath);
                },
                fail: () => {
                    console.log('文件保存失败');
                }
            });

            // }


        })
    }

    // 版本比较工具
    compareVersion(v1, v2) {
        const arr1 = v1.split('.');
        const arr2 = v2.split('.');
        for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) {
            const num1 = parseInt(arr1[i] || 0);
            const num2 = parseInt(arr2[i] || 0);
            if (num1 > num2) return 1;
            if (num1 < num2) return -1;
        }
        return 0;
    }

    // 绘制缩率图用的canvas
    thumbCanvas: Taro.OffscreenCanvas = Taro.createOffscreenCanvas({
        type: '2d',
        width: 1024,
        height: 1024,
    });

    // 获取一张正面的缩率图
    async getFrontThumb(): Promise<string> {
        this.controls.enableDamping = false;
        const originCameraPosition = this.camera.position.clone();
        const front_clothVisible = this.front_cloth.visible;
        const back_clothVisible = this.back_cloth.visible;
        const mockupGroupVisible = this.mockupGroup.visible;
        const type = this.type;

        const thumbs = [];
        const previewThumb = [];
        const { goodsBaseData } = designerStore;
        //升华
        if (["升华"].includes(goodsBaseData.secondaryCraftName)) {
            this.type = "3D";
            this.front_cloth.visible = true;
            this.back_cloth.visible = true;
            this.mockupGroup.visible = false;
            this.camera.position.set(0, 0, 10);
            this.camera.lookAt(new Vector3(0, 0, 0));
            const thumb = await this.exportImage();
            this.controls.enableDamping = true;
            return thumb;
        } else if (["烫画", "直喷"].includes(goodsBaseData.secondaryCraftName)) {

            // 渲染前片的缩率图
            const ctx = this.thumbCanvas.getContext('2d');
            ctx.clearRect(0, 0, 1024, 1024);

            const { colors } = goodsBaseData.data;
            const { selectColorValue } = designerStore;
            const currentColor = colors.find((c) => c.color === selectColorValue);
            if (currentColor) {
                if (currentColor.frontImg) {
                    // 创建图片实例
                    const image = await new Promise<Taro.Image | undefined>(async (resolve) => {
                        const image = this.thumbCanvas.createImage();
                        image.onload = () => {
                            resolve(image);
                        }
                        image.error = () => {
                            resolve(undefined);
                        }
                        image.src = utils.ossSuffix(currentColor.frontImg, 1024);
                    });

                    if (image.width) {
                        ctx.drawImage(image, 0, 0, 1024, 1024);
                    }

                    const fronTextureCanvas = textureManager.getTransparentCanvas("front");
                    if (fronTextureCanvas) {
                        ctx.drawImage(fronTextureCanvas, 0, 0, 1024, 1024);
                    }
                } else {
                    return undefined;
                }
            } else {
                return undefined;
            }

            return new Promise((resolve, reject) => {
                Taro.canvasToTempFilePath({
                    canvas: this.thumbCanvas,
                    success: async (res) => {
                        resolve(res.tempFilePath);
                    }
                });
            });

        }
    }
    // 获取一张背面缩率图
    async getBackThumb(): Promise<string | undefined> {
        this.controls.enableDamping = false;
        const originCameraPosition = this.camera.position.clone();
        const front_clothVisible = this.front_cloth.visible;
        const back_clothVisible = this.back_cloth.visible;
        const mockupGroupVisible = this.mockupGroup.visible;
        const type = this.type;

        const thumbs = [];
        const previewThumb = [];
        const { goodsBaseData } = designerStore;
        //升华
        if (["升华"].includes(goodsBaseData.secondaryCraftName)) {
            this.type = "3D";
            this.front_cloth.visible = true;
            this.back_cloth.visible = true;
            this.mockupGroup.visible = false;
            this.camera.position.set(0, 0, -10);
            this.camera.lookAt(new Vector3(0, 0, 0));
            const thumb = await this.exportImage();
            this.controls.enableDamping = true;
            return thumb;
        } else if (["烫画", "直喷"].includes(goodsBaseData.secondaryCraftName)) {

            // 渲染前片的缩率图
            const ctx = this.thumbCanvas.getContext('2d');
            ctx.clearRect(0, 0, 1024, 1024);

            const { colors } = goodsBaseData.data;
            const { selectColorValue } = designerStore;
            const currentColor = colors.find((c) => c.color === selectColorValue);
            if (currentColor) {
                if (currentColor.backImg) {
                    // 创建图片实例
                    const image = await new Promise<Taro.Image | undefined>(async (resolve) => {
                        const image = this.thumbCanvas.createImage();
                        image.onload = () => {
                            resolve(image);
                        }
                        image.error = () => {
                            resolve(undefined);
                        }
                        image.src = utils.ossSuffix(currentColor.backImg, 1024);
                    });

                    if (image.width) {
                        ctx.drawImage(image, 0, 0, 1024, 1024);
                    }

                    const fronTextureCanvas = textureManager.getTransparentCanvas("back");
                    if (fronTextureCanvas) {
                        ctx.drawImage(fronTextureCanvas, 0, 0, 1024, 1024);
                    }
                } else {
                    return undefined;
                }
            } else {
                return undefined;
            }

            return new Promise((resolve, reject) => {
                Taro.canvasToTempFilePath({
                    canvas: this.thumbCanvas,
                    success: async (res) => {
                        resolve(res.tempFilePath);
                    }
                });
            });

        }
    }


    // 获取全部缩率图
    async getAllImage() {
        this.controls.enableDamping = false;
        const originCameraPosition = this.camera.position.clone();
        const front_clothVisible = this.front_cloth.visible;
        const back_clothVisible = this.back_cloth.visible;
        const mockupGroupVisible = this.mockupGroup.visible;
        const type = this.type;

        const thumbs = [];
        const previewThumb = [];
        const { goodsBaseData } = designerStore;
        //升华
        if (["升华"].includes(goodsBaseData.secondaryCraftName)) {
            this.type = "3D";
            this.front_cloth.visible = true;
            this.back_cloth.visible = true;
            this.mockupGroup.visible = false;
            this.camera.position.set(0, 0, 10);
            this.camera.lookAt(new Vector3(0, 0, 0));
            thumbs.push(await this.exportImage());
            this.camera.position.set(0, 0, -10);
            this.camera.lookAt(new Vector3(0, 0, 0));
            thumbs.push(await this.exportImage());

            this.type = "2D";
            this.front_cloth.visible = false;
            this.back_cloth.visible = false;
            this.mockupGroup.visible = true;
            for (let mesh of this.mockupGroup.children) {
                this.mockupGroup.children.map((mockupMesh) => {
                    mockupMesh.visible = false;
                });
                mesh.visible = true;
                previewThumb.push(await this.exportImage());
            }
            //局部印
        } else if (["烫画", "直喷"].includes(goodsBaseData.secondaryCraftName)) {
            this.type = "2D";
            const urls = [];
            this.front_cloth.visible = false;
            this.back_cloth.visible = false;
            this.mockupGroup.visible = true;
            for (let mesh of this.mockupGroup.children) {
                this.mockupGroup.children.map((mockupMesh) => {
                    mockupMesh.visible = false;
                });
                mesh.visible = true;
                urls.push(await this.exportImage());
            }

            const [fontUrl, backUrl, ...other] = urls;
            fontUrl && thumbs.push(fontUrl);
            backUrl && thumbs.push(backUrl);
            previewThumb.push(...other);
        }

        this.camera.position.copy(originCameraPosition);
        this.camera.lookAt(new Vector3(0, 0, 0));
        this.front_cloth.visible = front_clothVisible;
        this.back_cloth.visible = back_clothVisible;
        this.mockupGroup.visible = mockupGroupVisible;
        this.mockupGroup.children.map((mockupMesh, i) => {
            mockupMesh.visible = (i === preView2D3DStore.activeMockup);
        });
        this.type = type;

        this.render();

        this.controls.enableDamping = true;

        return {
            thumbs,
            previewThumb
        }

    }

}

const perview3der = new Perview3der();

// 监听相机距离的变化
const dispose1 = autorun(() => {
    const { cameraDistance } = preView2D3DStore;
    perview3der.camera.position.setLength(cameraDistance);
    perview3der.camera.lookAt(new Vector3(0, 0, 0));
    perview3der.requestRender();
});

// 监听2D3D切换
const dispose2 = autorun(() => {
    const { showType } = preView2D3DStore;
    perview3der.type = showType;
    perview3der.front_cloth.visible = (showType === "3D");
    perview3der.back_cloth.visible = (showType === "3D");
    perview3der.mockupGroup.visible = (showType === "2D");
    if (showType === "3D") {
        if (perview3der.controls) {
            perview3der.controls.dampingFactor = 0.1;
        }
        preView2D3DStore.setCameraDistance(10);
        perview3der.camera.position.set(0, 0, 10);
        perview3der.camera.lookAt(new Vector3(0, 0, 0));
        perview3der.setIntensity(0.35);//3d模型合适的灯光强度
    } else if (showType === "2D") {
        perview3der.setIntensity(0.35);//2d模型合适的灯光强度
        if (perview3der.controls) {
            perview3der.controls.dampingFactor = 1;//增加阻尼可以让控制器快速停止
        }
    }
    perview3der.requestRender();
});

// 监听上身效果的切换
const dispose3 = autorun(() => {
    const { activeMockup } = preView2D3DStore;
    perview3der.mockupGroup.children.map((mesh, i) => {
        mesh.visible = (i === activeMockup);
    });
    perview3der.colorMockupGroup.children.map((mesh, i) => {
        mesh.visible = ((i - perview3der.mockupGroup.children.length) === activeMockup);
    });
    perview3der.requestRender();
});

//监听缝线的变化
const dispose4 = autorun(() => {
    const { threadColor } = designerStore;
    perview3der.front_cloth.traverse((mesh) => {
        if (mesh.isMesh && mesh.name.includes('thread')) {
            console.log(2, "threadColor", mesh.name, threadColor);
            mesh.material.color = new Color(threadColor);
        }
    });
    perview3der.requestRender();
}, { delay: 30 });

//监听更新时间来执行渲染
const dispose5 = autorun(() => {
    const { designData, needUpdateTime } = designerStore;
    if (needUpdateTime > 0) {
        const { colorValue } = designData;
        perview3der.mockupGroup.children.map((mockupMesh) => {
            mockupMesh.traverse((mesh) => {
                if (/^cloth(\d+)?$/.test(mesh.name)) {
                    // 颜色整体提亮避免黑色时看不到细节
                    const colorObject = new Color(colorValue);
                    const max = Math.max(...colorObject.toArray());
                    const colorInterval = 1 - max;
                    colorObject.r += colorInterval * 0.01;
                    colorObject.g += colorInterval * 0.01;
                    colorObject.b += colorInterval * 0.01;
                    ((mesh).material).color.copy(colorObject);
                }
            });
        });
        perview3der.requestRender();
    }
}, { delay: 30 });

export default perview3der;